package cn.com.nes.site.service.crm.customer.impl;

import cn.com.nes.common.em.DictTypeEnum;
import cn.com.nes.common.exception.MissBusinessParameterException;
import cn.com.nes.common.util.XzqhUtils;
import cn.com.nes.mybatis.agent.crm.entity.CustomerHouse;
import cn.com.nes.mybatis.agent.crm.entity.CustomerHouseRelationship;
import cn.com.nes.mybatis.agent.crm.mapper.CustomerHouseMapper;
import cn.com.nes.site.entity.PageData;
import cn.com.nes.site.entity.bo.workorder.ReplenishHouseInfoByCustomerBO;
import cn.com.nes.site.entity.em.DeleteEnum;
import cn.com.nes.site.entity.vo.NullVO;
import cn.com.nes.site.entity.vo.crm.CustomerHouseRelationshipVO;
import cn.com.nes.site.entity.vo.crm.CustomerHouseVO;
import cn.com.nes.site.entity.vo.crm.DelCustomerHouseInfoVO;
import cn.com.nes.site.entity.vo.crm.GetCustomerHousePageVO;
import cn.com.nes.site.entity.vo.workOrder.ReplenishHouseInfoVO;
import cn.com.nes.site.service.crm.customer.CustomerHouseRelationshipService;
import cn.com.nes.site.service.crm.customer.CustomerHouseService;
import cn.com.nes.site.service.crm.customer.bo.CustomerHouseBO;
import cn.com.nes.site.service.crm.customer.dto.CustomerHouseDTO;
import cn.com.nes.site.service.crm.customer.dto.HouseDTO;
import cn.com.nes.site.service.system.dict.TParamService;
import cn.com.nes.site.service.workOrder.CallWorkOrderInfoService;
import cn.com.nes.site.service.workOrder.WorkOrderService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * 客户房屋信息实现
 */
@Service
@Slf4j
public class CustomerHouseServiceImpl extends ServiceImpl<CustomerHouseMapper, CustomerHouse> implements CustomerHouseService {

    @Resource
    private CustomerHouseRelationshipService customerHouseRelationshipService;

    @Resource
    private CallWorkOrderInfoService callWorkOrderInfoService;

    @Resource
    private TParamService tParamService;

    @Resource
    private WorkOrderService workOrderService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CustomerHouse saveHouseInfo(CustomerHouseVO vo) {
        CustomerHouse customerHouse = new CustomerHouse();
        BeanUtils.copyProperties(vo,customerHouse);

        boolean flag = false;
        if (Objects.isNull(customerHouse.getId())) {
            customerHouse.setHouseUuid(UUID.randomUUID().toString());
            customerHouse.setCompanyId(vo.getOperateUserCompanyId());
            customerHouse.setGmtCreate(new Date());
            customerHouse.setGmtCreateId(Long.valueOf(vo.getUserInfo().getId()));
            customerHouse.setDeleted(0); // 0 - 没删除
            flag = true;
        }
        customerHouse.setGmtModified(new Date());
        customerHouse.setGmtModifiedId(Long.valueOf(vo.getUserInfo().getId()));
        if (ObjectUtil.isNotEmpty(vo.getEnergyType())) {
            customerHouse.setEnergyType(vo.getEnergyType());
        }
        if (StrUtil.isNotEmpty(vo.getGasMeterNumber())) {
            customerHouse.setGasMeterNumbers(vo.getGasMeterNumber());
        }
        if (StrUtil.isNotEmpty(vo.getElectricityMeterNumber())) {
            customerHouse.setElectricityMeterNumbers(vo.getElectricityMeterNumber());
        }


        this.saveOrUpdate(customerHouse);

        // 保存客户 - 房屋关系
        if (flag) {
            CustomerHouseRelationshipVO relationshipVO = new CustomerHouseRelationshipVO();
            relationshipVO.setCompanyId(customerHouse.getCompanyId());
            relationshipVO.setCustomerId(customerHouse.getCustomerId());
            relationshipVO.setHouseId(customerHouse.getId());
            relationshipVO.setUserInfo(vo.getUserInfo());
            customerHouseRelationshipService.saveRelationship(relationshipVO);
        }

        return customerHouse;
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public CustomerHouse saveCustomerHouse(CustomerHouseBO customerHouseBO) {
        CustomerHouse customerHouse = this.getCustomerHouse(customerHouseBO.getHouseUuid());
        BeanUtils.copyProperties(customerHouseBO,customerHouse);
        if (customerHouseBO.isAdd()) {
            customerHouse.setHouseUuid(UUID.randomUUID().toString());
            customerHouse.setCompanyId(customerHouseBO.getOperateUserCompanyId());
            customerHouse.setCustomerId(customerHouseBO.getCustomerUuid());
            customerHouse.setGmtCreate(customerHouseBO.getOperateDate());
            customerHouse.setGmtCreateId(customerHouseBO.getOperateUserId());
            customerHouse.setDeleted(DeleteEnum._0.getKey());
        } else {
            customerHouse.setCompanyId(customerHouseBO.getOperateUserCompanyId());
            customerHouse.setGmtModified(customerHouseBO.getOperateDate());
            customerHouse.setGmtModifiedId(customerHouseBO.getOperateUserId());
        }

        this.saveOrUpdate(customerHouse);

        CustomerHouseRelationship customerHouseRelationship = customerHouseRelationshipService.getCustomerHouseRelationship(customerHouse.getCustomerId(), customerHouse.getId());
        if (ObjectUtil.isNull(customerHouseRelationship)) {
            customerHouseRelationship = new CustomerHouseRelationship();
            customerHouseRelationship.setCompanyId(customerHouse.getCompanyId());
            customerHouseRelationship.setCustomerId(customerHouse.getCustomerId());
            customerHouseRelationship.setHouseId(customerHouse.getId());
            customerHouseRelationship.setDeleted(DeleteEnum._0.getKey());
            customerHouseRelationship.setGmtCreate(customerHouseBO.getOperateDate());
            customerHouseRelationship.setGmtCreateId(customerHouseBO.getOperateUserId());
            customerHouseRelationshipService.saveOrUpdate(customerHouseRelationship);
        }

        return customerHouse;
    }

    @Override
    public CustomerHouse getCustomerHouse(String houseUuid) {
        if (StrUtil.isNotEmpty(houseUuid)) {
            CustomerHouse customerHouse = getHouse(houseUuid);
            return ObjectUtil.isNull(customerHouse) ? new CustomerHouse() : customerHouse;
        }
        return new CustomerHouse();
    }

    @Override
    public CustomerHouse getCustomerHouse(String areaCode, String address, String customerUuid) throws Exception {
        LambdaQueryWrapper<CustomerHouse> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CustomerHouse::getDeleted, DeleteEnum._0.getKey());
        wrapper.eq(CustomerHouse::getAreaCode, areaCode);
        wrapper.eq(CustomerHouse::getAddress, address);
        wrapper.eq(CustomerHouse::getCustomerId, customerUuid);
        return this.getOne(wrapper);
    }

    @Override
    public CustomerHouse getHouse(String houseUuid) {
        LambdaQueryWrapper<CustomerHouse> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CustomerHouse::getHouseUuid, houseUuid);
        wrapper.eq(CustomerHouse::getDeleted, DeleteEnum._0.getKey());
        return this.getOne(wrapper);
    }

    @Override
    public CustomerHouseDTO getHouseDetail(Long houseId) throws Exception {
        CustomerHouse customerHouse = this.baseMapper.selectById(houseId);

        CustomerHouseDTO houseDetail = new CustomerHouseDTO();
        if (ObjectUtil.isNull(customerHouse)) {
            return houseDetail;
        }

        BeanUtils.copyProperties(customerHouse, houseDetail);
        houseDetail.setIsVillage(handleBooleanValue(customerHouse.getIsVillage()));
        houseDetail.setOuterWallKeepWarm(handleBooleanValue(customerHouse.getOuterWallKeepWarm()));
        setHouseDetailFields(houseDetail);
        return houseDetail;
    }

    private Boolean handleBooleanValue(String stringValue) {
        if (StrUtil.isBlank(stringValue)) {
            return null;
        }
        if ("0".equals(stringValue)) {
            return Boolean.FALSE;
        }
        if ("1".equals(stringValue)) {
            return Boolean.TRUE;
        }
        return Boolean.valueOf(stringValue);
    }

    @Override
    public HouseDTO getHouseDetail(String houseUuid) {
        CustomerHouse customerHouse = this.getCustomerHouse(houseUuid);
        if (ObjectUtil.isNull(customerHouse)) {
            return new HouseDTO();
        }
        HouseDTO houseDTO = new HouseDTO();
        BeanUtils.copyProperties(customerHouse, houseDTO);
        return houseDTO;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void replenishHouseInfo(ReplenishHouseInfoVO vo) throws Exception {
        // 获取房屋详情
        CustomerHouse customerHouse = this.baseMapper.selectById(vo.getHouseId());
        if (ObjectUtil.isNull(customerHouse)) {
            throw new Exception("房屋信息不存在!houseId = " + vo.getHouseId());
        }
        // 补充房屋信息 - 以入参为准
        customerHouse.setIsVillage(vo.getIsVillage());
        customerHouse.setCommonHeatingArea(vo.getCommonHeatingArea());
        customerHouse.setBuildingHeight(vo.getBuildingHeight());
        customerHouse.setBuildingStructure(vo.getBuildingStructure());
        customerHouse.setOuterWallKeepWarm(vo.getOuterWallKeepWarm());
        customerHouse.setHeatingMode(vo.getHeatingMode());
        customerHouse.setHousePerpose(vo.getHousePerpose());
        customerHouse.setRoomCount(vo.getRoomCount());
        customerHouse.setDesignUnit(StrUtil.isBlank(vo.getDesignUnit()) ? customerHouse.getDesignUnit() : vo.getDesignUnit());
        customerHouse.setDrawingNo(StrUtil.isBlank(vo.getDrawingNo()) ? customerHouse.getDrawingNo() : vo.getDrawingNo());
        customerHouse.setWindowType(vo.getWindowType());
        customerHouse.setDesignHeatingLoad(vo.getDesignHeatingLoad());
        customerHouse.setHouseDirection(vo.getHouseDirection());
        customerHouse.setEndState(vo.getEndState());
        customerHouse.setGmtModified(new Date());
        customerHouse.setGmtModifiedId(Long.valueOf(vo.getUserInfo().getId()));
        customerHouse.setFloorSpace(vo.getFloorSpace());
        customerHouse.setHeatingArea(vo.getHeatingArea());
        customerHouse.setHeatingEnd(vo.getHeatingEnd());
        customerHouse.setOuterWallThickness(vo.getOuterWallThickness());
        customerHouse.setInstallPosition(vo.getInstallPosition());
        customerHouse.setResidentCount(vo.getResidentCount());

        this.baseMapper.updateById(customerHouse);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void replenishHouseInfoByCustomer(ReplenishHouseInfoByCustomerBO bo) throws Exception {
        // 查询房屋信息
        Long houseId = callWorkOrderInfoService.getHouseIdByWorkOrderId(bo.getWorkOrderId());
        if (ObjectUtil.isNull(houseId)) {
            log.info("未查询到关联的房屋信息id,保存客户相关的房屋信息失败!");
            return;
        }

        CustomerHouse customerHouse = new CustomerHouse();
        customerHouse.setId(houseId);
        customerHouse.setAreaCode(bo.getAreaCode());
        customerHouse.setAddress(bo.getAddress());
        customerHouse.setHouseNumber(bo.getHouseNumber());
        customerHouse.setElectricityMeterNumbers(bo.getElectricityMeterNumbers());

        this.baseMapper.updateById(customerHouse);
    }

    /**
     * 查询客户房屋供暖所需制热量
     */
    @Override
    public BigDecimal getHouseNeedHeat(Long houseId) throws Exception {
        // 查询房屋信息
        CustomerHouseDTO houseDetail = getHouseDetail(houseId);
        // 计算所需制热量
        BigDecimal heatingArea = Objects.isNull(houseDetail.getHeatingArea()) ? BigDecimal.ZERO : houseDetail.getHeatingArea();
        BigDecimal designHeatingLoad = Objects.isNull(houseDetail.getDesignHeatingLoad()) ? BigDecimal.ZERO : houseDetail.getDesignHeatingLoad();
        return heatingArea.multiply(designHeatingLoad);
    }

    @Override
    public CustomerHouse getHouseInfo(String houseUuid) throws Exception {
        LambdaQueryWrapper<CustomerHouse> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CustomerHouse::getHouseUuid, houseUuid);
        wrapper.eq(CustomerHouse::getDeleted, DeleteEnum._0.getKey());
        CustomerHouse customerHouse = this.baseMapper.selectOne(wrapper);
        if (ObjectUtil.isNull(customerHouse)) {
            return null;
        }
        return customerHouse;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByCustomerIds(List<String> customerIdList, Long operateUserId, Date operateDate) {
        if (CollUtil.isEmpty(customerIdList)) {
            throw new MissBusinessParameterException("请传入要删除的客户ID");
        }
        this.baseMapper.deleteByCustomerIds(customerIdList, operateUserId, operateDate);
    }

    @Override
    public List<Long> getHouseIdListByHouseNumber(String houseNumber) {
        return this.baseMapper.getHouseIdListByHouseNumber(houseNumber);
    }

    @Override
    public Page<HouseDTO> getHousePage(CustomerHouseBO customerHouseBO) {
        Page<HouseDTO> page = new Page<>(customerHouseBO.getPageid(), customerHouseBO.getPagesize());
        customerHouseBO.setAreaCode(XzqhUtils.getRegionCodePrefix(customerHouseBO.getAreaCode()));
        List<HouseDTO> houseDTOS = this.baseMapper.getCustomerHousePage(page, customerHouseBO);
        page.setRecords(houseDTOS);
        return page;
    }

    @Override
    public Page<CustomerHouseDTO> getHousePage(GetCustomerHousePageVO vo) throws Exception {
        Page<CustomerHouseDTO> page = new Page<>(vo.getPageid(), vo.getPagesize());
        List<CustomerHouseDTO> houseDTOList = this.baseMapper.getHousePage(page, vo.getCustomerUuid());

        List<CustomerHouseDTO> houseList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(houseDTOList)) {
            for (CustomerHouseDTO customerHouseDTO : houseDTOList) {
                houseList.add(this.getHouseDetail(customerHouseDTO.getId()));
            }
        }
        page.setRecords(houseList);
        return page;
    }

    @Override
    public List<CustomerHouseDTO> getCustomerHouse(GetCustomerHousePageVO vo) throws Exception {
        List<CustomerHouseDTO> houseDTOList = this.baseMapper.getHousePage(new Page<>(), vo.getCustomerUuid());
        List<CustomerHouseDTO> houseList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(houseDTOList)) {
            for (CustomerHouseDTO customerHouseDTO : houseDTOList) {
                houseList.add(this.getHouseDetail(customerHouseDTO.getId()));
            }
        }
        return houseList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PageData delHouseInfo(DelCustomerHouseInfoVO vo) throws Exception {
        CustomerHouse customerHouse = new CustomerHouse();
        customerHouse.setId(vo.getHouseId());
        customerHouse.setDeleted(1);
        customerHouse.setGmtModifiedId(vo.getOperateUserId());
        customerHouse.setGmtModified(vo.getOperateDate());
        int rows = this.baseMapper.updateById(customerHouse);
        if (1 != rows) {
            throw new Exception("删除客户房屋失败,房屋id:" + vo.getHouseId());
        }
        // 删除客户房屋关系数据
        customerHouseRelationshipService.delRelationship(vo.getHouseId());

        return PageData.ok();
    }

    @Override
    public PageData saveHouseDropdownBox(NullVO vo) throws Exception {
        return workOrderService.replenishHouseDropdownBox(vo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CustomerHouse queryOrSaveCustomerHouse(CustomerHouseBO customerHouseBO) {
        QueryWrapper<CustomerHouse> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("address", customerHouseBO.getAddress());
        queryWrapper.eq("deleted", false);
        queryWrapper.last("order by id desc limit 1");

        List<CustomerHouse> customerHouses = this.baseMapper.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(customerHouses)) {
            return customerHouses.get(0);
        }

        return this.saveCustomerHouse(customerHouseBO);
    }

    private void setHouseDetailFields(CustomerHouseDTO item) {
        if (ObjectUtil.isNull(item)) {
            return;
        }

        item.setBuildingStructureName(tParamService.getNameByParamTypeAndValue(DictTypeEnum.BUILDING_STRUCTURE.getParamType(), String.valueOf(item.getBuildingStructure())));
        item.setHeatingModeName(tParamService.getNameByParamTypeAndValue(DictTypeEnum.HEATING_MODE.getParamType(), String.valueOf(item.getHeatingMode())));
        item.setHousePerposeName(tParamService.getNameByParamTypeAndValue(DictTypeEnum.HOUSE_PERPOSE.getParamType(), String.valueOf(item.getHousePerpose())));
        item.setWindowTypeName(tParamService.getNameByParamTypeAndValue(DictTypeEnum.WINDOW_TYPE.getParamType(), String.valueOf(item.getWindowType())));
        item.setHouseDirectionName(tParamService.getNameByParamTypeAndValue(DictTypeEnum.HOUSE_DIRECTION.getParamType(), String.valueOf(item.getHouseDirection())));
        item.setEndStateName(tParamService.getNameByParamTypeAndValue(DictTypeEnum.END_STATE.getParamType(), String.valueOf(item.getEndState())));
        item.setHeatingEndName(tParamService.getNameByParamTypeAndValue(DictTypeEnum.HEATING_END.getParamType(), ObjectUtil.isNull(item.getHeatingEnd()) ? "0" : String.valueOf(item.getHeatingEnd())));
        item.setOuterWallThicknessName(tParamService.getNameByParamTypeAndValue(DictTypeEnum.OUTER_WALL_THICKNESS.getParamType(), String.valueOf(item.getOuterWallThickness())));
        item.setInstallPositionName(tParamService.getNameByParamTypeAndValue(DictTypeEnum.INSTALL_POSITION.getParamType(), String.valueOf(item.getInstallPosition())));
        item.setHouseTypeName(tParamService.getNameByParamTypeAndValue(DictTypeEnum.HOUSE_TYPE.getParamType(), String.valueOf(item.getHouseType())));
        item.setEnergyTypeName(tParamService.getNameByParamTypeAndValue(DictTypeEnum.ENERGY_TYPE.getParamType(), String.valueOf(item.getEnergyType())));
    }
}
